#ifndef DESCRIPTIONS_H
#   define DESCRIPTIONS_H

#include "tab_dyn_id.h"
#include "inventaire.h"


/**
 * \struct description_ennemi descriptions.h
 * Structure destinee a etre stockee en grand nombre dans une base_donnee afin
 * de tout savoir sur tous les ennemis en n'ayant a lire un fichier texte
 * qu'une seule fois.
 */
struct description_ennemi
{
    char nom[32];
    /**
     * localisation_sprites donne la position verticale de la ligne du fichier
     * de sprites qui contient ceux de l'ennemi concerne. Ce nombre n'est ici
     * pas donne en pixels mais en nombre de cases, afin que les humains
     * s'y retrouvent mieux. Rappel :  les cases font 16 pixels de large
     */
    unsigned int localisation_sprites;
    unsigned int pv;
    unsigned int vitesse_deplacement;
    unsigned int puissance;
    unsigned int vitesse_charge;
    unsigned char id_projectile;
    /** la taille est donnee en nombre de cases de large. 1 au minimum */
    unsigned char taille;
    /** type_attaque = CONTACT ou DISTANCE */
    char type_attaque;
    /** volant = VRAI ou FAUX */
    char volant;
    /** liste des id des objets que l'ennemi peut laisser en etant vaincu */
    struct tab_dyn_id drops;
    /** liste des probabilites d'obtenir chacun des drops */
    struct tab_dyn_id probas;
};



/**
 * \struct tab_dyn_description_ennemis descriptions.h
 * Tableau contenant la description de tous les ennemis du jeu. le but est
de n'avoir a faire le parsing qu'une seule fois
 */
struct tab_dyn_description_ennemis
{
    struct description_ennemi* tab;
    unsigned int nb_elements;
};



/**
 * \struct description_projectile descriptions.h
 * Permet de connaitre les caracteristiques immuables d'un projectile.
 * Cette structure est utilisee dans la structure base_donnees, dans laquelle
 * on pioche les informations dont on a besoin
 */
struct description_projectile
{
    /**
     * localisation_sprites donne la position verticale de la ligne du fichier
     * de sprites qui contient ceux du projectile concerne. Ce nombre n'est ici
     * pas donne en pixels mais en nombre de cases, afin que les humains
     * s'y retrouvent mieux.\n
     * Rappel :  les cases font 16 pixels de large.
     * La premiere ligne est donc designee par 0, la ligne situee 16 pixels en
     * dessous est 1, et ainsi de suite.
     */
    unsigned int localisation_sprites;
    unsigned int vitesse_deplacement;
    unsigned char taille;
};


/**
 * \struct tab_dyn_description_projectiles descriptions.h
 * La description de tous les projectiles du jeu
 */
struct tab_dyn_description_projectiles
{
    struct description_projectile* tab;
    unsigned int nb_elements;
};



/**
 * \struct description_objet descriptions.h
 * Structure destinee a etre stockee en grand nombre dans une base_donnee afin
 * de tout savoir sur tous les objets en n'ayant a lire un fichier texte qu'une
 * seule fois.
 */
struct description_objet
{
    char nom[32];
    /**
     * Le type d'un objet est definie par un char auquel on affectera des
     * valeurs en utilisant les constantes prevues a cet effet. Ainsi, ce type
     * pourra etre :\n
     * MATERIAU, UTILISABLE, ARME, VESTE, GANT, CHAUSSURE, ACCESSOIRE.\n
     * Les materieux peuvent etre vendus ou utilises pour fabriquer d'autres
     * objets. Les objets utilisables peuvent, comme leur nom l'indique, etre
     * utilises durant les batailles et servent a aider le joueur. Notez bien
     * que ces objets disparaissent lors de leur utilisation. Les cinq derniers
     * types d'objets sont les equipements. Le joueur peut en porter un de
     * chaque type afin d'augmenter ses capacites.\n
     * Notez qu'il est impossible de n'avoir aucune arme
     * equipee, ce qui n'est pas le cas pour les quatres
     * autres categories
     */
    char type;
    /**
     * Concernant les pv, si il s'agit d'un objet utilisable, il sagit de soin.
     * Les pv max du joueur ne sont alors pas affectes. Si il sagit d'un
     * equipement, il sagira cette fois-ci d'une augmentation des pv max.
     */
    unsigned int pv;
    unsigned int vitesse_deplacement;
    /**
     * Les champs pv, vitesse_deplacement, puissance, vitesse_charge decrivent,
     * pour un objet utilisable, une
     * amelioration des competences qui dure jusqu'a la fin de la bataille,
     * et, pour une equipement, une amelioration constante. Ils n'ont aucune
     * utilite pour les materiaux, mais il aurait ete laborieux de faire
     * une autre structure specialement pour eux. Beaucoup de fonctions les
     * traitent comme des objets comme les autres, tout est plus clair comme ca
     */
    unsigned int puissance;
    unsigned int vitesse_charge;
    /**
     * Le champ id_projectile ne concerne que les armes et permet de connaitre
     * le type de projectile tire par chacune d'entre-elles
     */
    unsigned char id_projectile;
    /**
     * Le prix de vente permet de connaitre la somme d'argent que le joueur
     * peut obtenir en vendant l'objet
     */
    unsigned int prix_vente;
};



/**
 * \struct tab_dyn_description_objets descriptions.h
 * Tableau contenant la description de tous les objets du jeu. le but est
de n'avoir a faire le parsing qu'une seule fois
 */
struct tab_dyn_description_objets
{
    struct description_objet* tab;
    unsigned int nb_elements;
};



/**
 * \struct description_quete descriptions.h
 * Une structure qui decrit une quete : objet obtenu lors de
 * l'accomplissement et objets necessaires avec les quantites
 * correspondantes.
 */
struct description_quete
{
    /** id de l'objet obtenu */
    unsigned int recompense;
    /** objets necessaires */
    struct inventaire objets_necessaires;
};



/**
 * \struct tab_dyn_quetes descriptions.h
 * Une structure qui contient les descriptions de toutes les quetes du jeu.
 */
struct tab_dyn_quetes
{
    struct description_quete* tab;
    unsigned int nb_elements;
};



/**
 * \struct region descriptions.h
 * Structure permettant de stocker le nom d'une region,
 * son id, et sa position sur la carte du monde.
 */
struct region
{
    /** numero de la region */
    unsigned int id;
    /** nom de la region */
    char nom[32];
    /** coordonnee horizontale, en pixels, de la region sur la carte du monde */
    unsigned int coord_x;
    /** coordonnee verticale, en pixels, de la region sur la carte du monde */
    unsigned int coord_y;
};



/**
 * \struct tab_dyn_regions descriptions.h
 * Tableau dynamique permettant de stocker
 * des informations sur toutes les regions du jeu.\n
 * Comme beaucoup d'autres tableaux dynamiques de ce projet, sa taille est
 * fixee lors de l'initialisation et n'a ensuite aucune raison de changer.
 * En effet, il ne peut pas y avoir de nouvelle region ajoutee au jeu en
 * pleine partie.
 */
struct tab_dyn_regions
{
    /** pointeur vers le premier element du tableau */
    struct region* tab;
    /** nombre de regions repertoriees dans le tableau */
    unsigned int nb_elements;
};



/* ======================== ennemis =============================== */

/**
 * \fn void init_tab_dyn_description_ennemis(struct tab_dyn_description_ennemis* tab, const unsigned int taille)
 * \brief initialise un tableau de descriptions d'ennemis a la taille souhaitee
 *
 * \param[out] tab Un pointeur sur le tableau a initialiser
 * \param[in] taille Le nombre de case qu'aura le tableau
 * Ce tableau n'aura ensuite aucune raison de changer de taille !
 */
void init_tab_dyn_description_ennemis(struct tab_dyn_description_ennemis* tab, const unsigned int taille);



/**
 * \fn void ajouter_description_ennemi(struct tab_dyn_description_ennemis* tab, const struct description_ennemi* enn)
 * \brief Ajoute une description d'ennemi a un tab_dyn_description_ennemis
 *
 * \param[in,out] tab Un pointeur vers le tableau concerne
 * \param[in] enn Un pointeur vers un exemplaire de la description a ajouter
 */
void ajouter_description_ennemi(struct tab_dyn_description_ennemis* tab, const struct description_ennemi* enn);


/**
 * \fn void detruire_tab_dyn_description_ennemis(struct tab_dyn_description_ennemis* tab)
 * \brief Detruit un tab_dyn_description_ennemis en liberant la memoire qui lui a ete allouee
 *
 * \param tab Un pointeur vers le tableau a detruire
 */
void detruire_tab_dyn_description_ennemis(struct tab_dyn_description_ennemis* tab);


/* ======================== objets =============================== */

/**
 * \fn void init_tab_dyn_description_objets(struct tab_dyn_description_objets* tab, const unsigned int taille)
 * \brief initialise un tableau de descriptions d'objets a la taille souhaitee
 *
 * \param[out] tab Un pointeur sur le tableau a initialiser
 * \param[in] taille Le nombre de case qu'aura le tableau
 * Ce tableau n'aura ensuite aucune raison de changer de taille !
 */
void init_tab_dyn_description_objets(struct tab_dyn_description_objets* tab, const unsigned int taille);



/**
 * \fn void ajouter_description_objet(struct tab_dyn_description_objets* tab, const struct description_objet* obj)
 * \brief Ajoute une description d'objet a un tab_dyn_description_objets
 *
 * \param[in,out] tab Un pointeur vers le tableau concerne
 * \param[in] obj Un pointeur vers un exemplaire de la description a ajouter
 */
void ajouter_description_objet(struct tab_dyn_description_objets* tab, const struct description_objet* obj);


/**
 * \fn void detruire_tab_dyn_description_objets(struct tab_dyn_description_objets* tab)
 * \brief Detruit un tab_dyn_description_objets en liberant la memoire qui lui a ete allouee
 *
 * \param tab Un pointeur vers le tableau a detruire
 */
void detruire_tab_dyn_description_objets(struct tab_dyn_description_objets* tab);


/* ======================== projectiles =============================== */




/**
 * \fn void init_tab_dyn_description_projectiles(struct tab_dyn_description_projectiles* tab,
                                          const unsigned int taille)
 * \brief Prepare un tableau dynamique de descriptions de projectiles a etre rempli
 *
 * \param[out] tab L'adresse du tableau
 * \param[in] taille La taille que l'ont veut attribuer au tableau
 * Rappel : les tableaux de descriptions, contenus dans les bases_donnees, ont
une taille fixe. On les prepare a recevoir tout ce qui existe dans le jeu,
on les rempli, puis on ne les touche plus
 */
void init_tab_dyn_description_projectiles(struct tab_dyn_description_projectiles* tab,
                                          const unsigned int taille);


/**
 * \fn void ajouter_description_projectile(struct tab_dyn_description_projectiles* tab,
                                    const struct description_projectile* proj)
 * \brief Ajoute une description de projectile a un tab_dyn_description_projectiles
 *
 * \param[in,out] tab L'adresse du tableau concerne
 * \param[in] proj Un pointeur vers le projectile a ajouter (ses
caracteristiques seront copiees)
 */
void ajouter_description_projectile(struct tab_dyn_description_projectiles* tab,
                                    const struct description_projectile* proj);



/**
 * \fn void detruire_tab_dyn_description_projectiles(struct tab_dyn_description_projectiles* tab)
 * \brief Detruit un tab_dyn_description_projectiles en liberant la memoire qui lui a ete allouee
 *
 * \param tab Un pointeur vers le tableau a detruire
 */
void detruire_tab_dyn_description_projectiles(struct tab_dyn_description_projectiles* tab);



/* ======================== quetes =============================== */


/**
 * \fn void init_tab_dyn_quetes(struct tab_dyn_quetes* quetes,
                            const unsigned int nb_quetes)
 * \brief Initialise un tableau de quetes
 *
 * \param[out] quetes Le tableau a initialiser
 * \param[in] nb_quetes La taille que l'on souhaite donner au tableau
 *
 * \warning Tout comme de nombreuses structures contenues dans les structures
 *          base_donnees, ce tableau se voit donner une taille a son
 *          initialisation, puis ne pourra pas etre agrandit. Il n'y a
 *          d'ailleurs aucune raison de vouloir l'agrandir : on lit le fichier
 *          quetes.txt au lancement du jeu, puis la liste des quetes reste
 *          inchangee.
 */
void init_tab_dyn_quetes(struct tab_dyn_quetes* quetes,
                     const unsigned int nb_quetes);



/**
 * \fn void init_prochaine_quete(struct tab_dyn_quetes* quetes,
                                 const unsigned int recompense)
 * \brief Initialise une nouvelle quete d'un tableau de quetes
 *
 * \param[in,out] quetes Le tableau de quetes concerne
 * \param[in] recompense L'id de l'objet obtenu lors
 *                       de l'accomplissement de la quete
 *
 * Cette fonction met fin aux modifications sur la quete dont on s'occupait
 * et permet de commencer les modifications sur la suivante.\n
 * Il est obligatoire de l'appeler pour chaque quete, meme pour la premiere.
 */
void init_prochaine_quete(struct tab_dyn_quetes* quetes,
                          const unsigned int recompense);



/**
 * \fn void modifier_derniere_quete(struct tab_dyn_quetes* quetes,
                                    const unsigned int id_objet,
                                    const unsigned int quantite)
 * \brief Permet de modifier la derniere quete qui a ete initialisee avec
 *        init_prochaine_quete.
 *
 * \param[in,out] quetes Le tableau de quetes que l'on utilise
 * \param[in] id_objet L'id de l'objet que l'on veut ajouter a la liste
 *                     d'objets necessaires de la quete
 * \param[in] quantite Le nombre d'exemplaires de l'objet id_objet qu'il faut
 *                     rassembler pour la quete
 *
 * Cette fonction ajoute un objet a la liste des objets necessaires d'une
 * quete, avec une quantite donnee.
 */
void modifier_derniere_quete(struct tab_dyn_quetes* quetes,
                             const unsigned int id_objet,
                             const unsigned int quantite);



/**
 * \fn void detruire_tab_dyn_quetes(struct tab_dyn_quetes* quetes)
 * \brief Libere la memoire allouee pour un tableau de descriptions de quetes
 *
 * \param[in] quetes L'adresse du tableau a detruire
 */
void detruire_tab_dyn_quetes(struct tab_dyn_quetes* quetes);



/* ======================== regions =============================== */


/**
 * \fn void init_tab_dyn_regions(struct tab_dyn_regions* tab, const unsigned int taille)
 * \brief Initialise un tableau dynamique de regions
 *
 * \param[out] tab L'adresse du tableau a initialiser
 * \param[in] taille La taille que l'on souhaite donner au tableau
 *
 * \warning La taille ne pourra pas etre modifiee par la suite ! De plus,
 *          elle ne peut pas etre nulle.
 */
void init_tab_dyn_regions(struct tab_dyn_regions* tab, const unsigned int taille);



/**
 * \fn void ajouter_region(struct tab_dyn_regions* tab, const unsigned int id,
                           const char* nom,
                           const unsigned int coord_x, const unsigned int coord_y)
 * \brief Ajoute une region a un tableau dynamique de regions
 *
 * \param[in,out] tab L'adresse du tableau concerne (prealablement initialise)
 * \param[in] id Le numero de la region a ajouter
 * \param[in] nom Le nom de la region a ajouter
 * \param[in] coord_x La coordonnee horizontale, en pixels,
 *                    de la region sur la carte du monde
 * \param[in] coord_y La coordonnee verticale, en pixels,
 *                    de la region sur la carte du monde
 *
 * \warning Attention a ne pas depasser la capacite fixee lors de l'initialisation !
 */
void ajouter_region(struct tab_dyn_regions* tab, const unsigned int id,
                    const char* nom,
                    const unsigned int coord_x, const unsigned int coord_y);


/**
 * \fn void detruire_tab_dyn_regions(struct tab_dyn_regions* tab)
 * \brief Libere la memoire allouee pour un tableau dynamique de regions
 *
 * \param[in] tab L'adresse du tableau, initialise, a detruire
 */
void detruire_tab_dyn_regions(struct tab_dyn_regions* tab);


#endif /* DESCRIPTIONS_H */
